package org.example.uhy.domain.model.coupon;

import org.example.uhy.domain.model.base.Operator;
import org.example.uhy.domain.model.base.TimeRange;
import org.example.uhy.exceptions.IllegalParameterException;
import org.example.uhy.supports.meta.Aggregate;

import java.time.LocalDateTime;

/**
 * 卡券定义
 * <p>
 * 需要确定一下，CouponArchive和CouponDefinition哪个命名更合适
 * <p>
 * 描述信息、发行数量、券类型、减免金额和条件、
 * 核销条件(门店、商品)、
 * 发放条件(张数、可否转赠、售卖、自领)、
 * 已发数量、可发数量
 * 领取的条件(粉丝或者会员)
 */
@Aggregate
public class CouponArchive {
    private transient CouponArchiveId archiveId; // ID
    private String name; // 卡券类型名称
    private String description;
    private transient TimeRange effectiveTime; // 有效期
    private transient CouponConstraint constraint; // 卡券限制条件
    private transient CouponParameter parameter;
    private CouponStock stock; // 可用数量
    private LocalDateTime createTime; // 卡券定义档案创建事件
    private String createUser; // // 卡券定义创建人

    private CouponArchive() {
    }

    public CouponArchive(CouponArchiveId id, String name, String description, TimeRange effectiveTime, Integer plannedQuantity, CouponConstraint constraint, CouponParameter parameter, Operator operator) {
        this.archiveId(id);
        this.setName(name);
        this.setDescription(description);
        this.setEffectiveTime(effectiveTime);
        this.setStock(new CouponStock(plannedQuantity, plannedQuantity));
        this.setConstraint(constraint);
        this.setParameter(parameter);
        this.setCreateTime(LocalDateTime.now());
        this.setCreateUser(operator.getOperatorId());
    }

    /**
     * 生成卡券
     * <p>
     * 这是一个创建卡券的工厂方法，生成卡券的时，进行了约束检查，并维护了卡券定义的可用数量内部状态
     *
     * @param couponId 卡券ID
     * @return
     */
    public Coupon generateCoupon(CouponId couponId) {
        // 扣减库存
        stock().reduce(1);
        // 约束校验，约束校验转移到资格检查领域服务{@link CouponAdmissionService}中
        // constraint().check();
        // 使用卡券工厂创建卡券
        // return new CouponFactory().create(couponId, this);
        // 只有卡券定义才最知道创建哪个类型的卡券，该卡券需要什么参数
        Coupon coupon = parameter.createCoupon(couponId, archiveId, name, effectiveTime);
        return coupon;
    }

    public CouponArchiveId archiveId() {
        return archiveId;
    }

    private void archiveId(CouponArchiveId archiveId) {
        if (archiveId == null) {
            throw new IllegalParameterException("请输入卡券定义ID");
        }
        this.archiveId = archiveId;
    }

    private String getId() {
        return this.archiveId.getId();
    }

    private void setId(String id) {
        this.archiveId = CouponArchiveId.of(id);
    }

    public String getName() {
        return name;
    }

    public void setName(String name) {
        if (name == null || name.length() == 0) {
            throw new IllegalParameterException("请输入卡券名称");
        }
        this.name = name;
    }

    public String getDescription() {
        return description;
    }

    private void setDescription(String description) {
        this.description = description;
    }

    public TimeRange effectiveTime() {
        return effectiveTime;
    }

    private TimeRange getEffectiveTime() {
        return effectiveTime;
    }

    private void setEffectiveTime(TimeRange effectiveTime) {
        if (effectiveTime == null) {
            throw new IllegalParameterException("请输入卡券有效期");
        }
        this.effectiveTime = effectiveTime;
    }

    public CouponConstraint constraint() {
        return constraint;
    }

    private CouponConstraint getConstraint() {
        return constraint;
    }

    private void setConstraint(CouponConstraint constraint) {
        if (constraint == null) {
            throw new IllegalParameterException("请输入卡券发放限制");
        }
        this.constraint = constraint;
    }

    public CouponStock stock() {
        return stock;
    }

    private CouponStock getStock() {
        return stock;
    }

    private void setStock(CouponStock stock) {
        if (stock == null) {
            throw new IllegalParameterException("请输入卡券库存数量");
        }
        this.stock = stock;
    }

    public CouponParameter parameter() {
        return parameter;
    }

    private CouponParameter getParameter() {
        return parameter;
    }

    private void setParameter(CouponParameter parameter) {
        if (parameter == null) {
            throw new IllegalArgumentException("请输入卡券参数");
        }
        this.parameter = parameter;
    }

    private LocalDateTime getCreateTime() {
        return createTime;
    }

    private void setCreateTime(LocalDateTime createTime) {
        this.createTime = createTime;
    }

    private String getCreateUser() {
        return createUser;
    }

    private void setCreateUser(String createUser) {
        if (createUser == null || createUser.length() == 0) {
            throw new IllegalArgumentException("请输入创建人");
        }
        this.createUser = createUser;
    }
}